package level

import (
	"github.com/syndtr/goleveldb/leveldb/util"
)

// Push 压栈.
func (p *Service) Push(key []byte, elems ...interface{}) {
	if len(elems) == 0 {
		return
	}

	mu := p.getMutex(key)

	mu.Lock()
	defer mu.Unlock()

	sk := []byte{ByteStack}
	sk = append(sk, key...)

	for _, elem := range elems {
		elemKey := p.NextSequenceDESC(sk)
		elemKey = append(sk, elemKey...)

		p.Put(elemKey, elem)
	}
}

// Pop 出栈.
func (p *Service) Pop(key []byte, elems ...interface{}) int {
	if len(elems) == 0 {
		return 0
	}

	mu := p.getMutex(key)

	mu.Lock()
	defer mu.Unlock()

	sk := []byte{ByteStack}
	sk = append(sk, key...)
	ran := util.BytesPrefix(sk)
	ret := 0

	iter := p.DB.NewIterator(ran, nil)
	for i := 0; i < len(elems) && iter.Next(); i++ {
		if err := Bytes2Interface(iter.Value(), elems[i]); err != nil {
			panic(err)
		}

		if err := p.DB.Delete(iter.Key(), nil); err != nil {
			panic(err)
		}

		ret++
	}

	return ret
}

// StackSize 栈内元素数量.
func (p *Service) StackSize(key []byte) int {
	sk := []byte{ByteStack}
	sk = append(sk, key...)
	ran := util.BytesPrefix(sk)
	size := 0

	iter := p.DB.NewIterator(ran, nil)
	for iter.Next() {
		size++
	}

	return size
}
